import random as rd
import string
from function import runLCS, runKnapsack
import time
import re
import matplotlib.pyplot as plt


def analysisLCS(length=None):
    if length is None or len(length) == 0:
        length = [10, 100, 300, 1000, 10000]
    print("使用", length, "进行不同数据量的测试")
    for l in length:
        x = []
        y = []
        tmp_l = l // 10
        while tmp_l <= l:
            a = ''.join(rd.choice(string.ascii_letters + string.digits) for _ in range(tmp_l))
            b = ''.join(rd.choice(string.ascii_letters + string.digits) for _ in range(tmp_l))
            start = time.time()
            runLCS(a, b)
            cost = time.time() - start
            x.append(tmp_l)
            y.append(cost)
            tmp_l += l // 10
        print(x, "\ncost: ", y)
        plt.plot(x, y, label='costLine')
        plt.title('analysis')
        plt.xlabel('X the length range')
        plt.ylabel('Y LCS cost seconds')
        plt.legend()
        plt.show()


def analysisKnapsack(N: int = None, cRange=None):
    if cRange is None or len(cRange) == 0:
        cRange = [5, 10, 50, 100, 500, 1000, 10000]  # 不同背包容量
        print("使用默认数据，背包容量列表：", cRange)
    if N is None:
        nRange = list(range(1, 10002, 500))  # 不同物品个数范围
        print("使用默认数据，物品个数列表：", nRange)
    else:
        if 10 <= N < 20:
            nRange = list(range(1, N, N//10))  # 不同物品个数范围
        else:
            nRange = list(range(1, N, N//20))  # 不同物品个数范围
    for c in cRange:
        x = nRange
        y = []
        for n in nRange:
            w = [rd.randint(1, c) for _ in range(n)]
            v = [rd.randint(1, 1000) for _ in range(n)]
            start = time.time()
            runKnapsack(n, c, w, v)
            cost = time.time() - start
            # x.append(n)
            y.append(cost)
        print("背包容量为%d时，测试数据如下:" % c)
        print("物品个数规模N:", x)
        print("花费时间COST:", y)
        plt.plot(x, y, label='costLine')
        plt.title('analysis')
        plt.xlabel('the Knapsack‘s N')
        plt.ylabel('cost seconds when C is %d ' % c)
        plt.legend()
        plt.show()


if __name__ == "__main__":
    choice = input("1.分析测试最长公共子序列问题\n"
                   "2.分析测试0-1背包问题\n"
                   "请输入您的选择：")
    choice = re.match('[1-2]', choice)
    try:
        choice = choice.group(0)
    except Exception:
        print("错误的输入")
    if choice == '1':
        print("你选择了1\n"
              "最长公共子序列问题分析测试")
        tmp_in = input("请输入两序列长度的最大范围N(整数或数组，小于10时无效，不输入时将使用默认数据)\n")
        regx = '[0-9]+'
        list_in = re.findall(regx, tmp_in)
        l_list = [int(x) for x in list_in if int(x) >= 10]
        analysisLCS(l_list)

    elif choice == '2':
        print("你选择了2\n"
              "0-1背包问题分析测试")
        tmp_in = input("请输入物品最大范围N(整数，小于10时无效，不输入时将使用默认数据)\n")
        regx = '[0-9]+'
        N_in = re.match(regx, tmp_in)
        try:
            N = int(N_in.group(0))
        except Exception:
            N = None
        tmp_in = input("请输入背包容量测试点(数组,为空时将使用默认数据)\n")
        regx = "([0-9]+(\.[0-9]+)?)"
        list_in = re.findall(regx, tmp_in)
        C_list = [float(x[0]) for x in list_in]
        analysisKnapsack(N, C_list)
